#include "messagedisplayarea.h"
#include "model/data.h"
#include "debug.h"

#include <QScrollBar>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QLabel>
#include <QFontMetrics>
#include <QPainter>
#include <QPainterPath>


MessageDisplayArea::MessageDisplayArea()
{
    // 1. 设置基本属性和样式
    // QString display_area_style = "QWidget { border: none; border-top: 1px solid rgb(231, 231, 231); }";
    // display_area_style += "QWidget { border-bottom: 1px solid rgb(236, 236, 236);}";
    this->setStyleSheet("QWidget { border: none; }");

    this->setWidgetResizable(true); // 重要重要重要！！！！
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    this->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 7px; border: 10px; background-color: rgb(210, 210, 210); }");
    this->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 0px; }");

    // 2. 设置 QScrollArea 内部 Widget
    container = new QWidget();
    this->setWidget(container);

    // 3. 添加纵置布局
    QVBoxLayout* vlayout = new QVBoxLayout();
    vlayout->setContentsMargins(31, 0, 31, 0);
    vlayout->setSpacing(0);
    container->setLayout(vlayout);

// 构造测试数据
#if UI_TEST
    for (int i = 0; i < 30; i++)
    {
        model::UserInfo user;
        user.userId = QString::number(100);
        user.avatar = QIcon(":/resource/image/myAvatar.jpg");
        user.nickname = QString("月朗天门");

        Message msg = Message::makeMessage(model::TEXT_MSG, "", user, QString("到达胜利之前无法回头").toUtf8(), "");
        PushMessage(true, msg);
        PushMessage(false, msg);
    }
#endif
}


void MessageDisplayArea::PushMessage(bool isLeft, const Message& msg)
{
    MessageItem* item = MessageItem::MakeMessageItem(isLeft, msg);
    QVBoxLayout* vlayout = dynamic_cast<QVBoxLayout*>(container->layout());
    vlayout->addWidget(item);
    // qDebug() << "push Message";
}

void MessageDisplayArea::PushFrontMessage(bool isLeft, const Message& msg)
{
    MessageItem* item = MessageItem::MakeMessageItem(isLeft, msg);
    QVBoxLayout* vlayout = dynamic_cast<QVBoxLayout*>(container->layout());
    vlayout->insertWidget(0, item);
}

void MessageDisplayArea::Clear()
{
    QVBoxLayout* vlayout = dynamic_cast<QVBoxLayout*>(container->layout());
    for (int i = vlayout->count()-1; i >= 0; i--)
    {
        QLayoutItem* item = vlayout->takeAt(i);
        if (item != nullptr && item->widget() != nullptr)
        {
            delete item->widget();
        }
    }
}

void MessageDisplayArea::ScrollToBottom()
{

}


MessageItem::MessageItem(bool isLeft)
    : is_left(isLeft)
{

}

// 工厂方法创建 MessageItem 实例
MessageItem* MessageItem::MakeMessageItem(bool isLeft, const Message& msg)
{
    // 1. 创建一个 MessageItem ，添加布局管理器
    MessageItem* item = new MessageItem(isLeft);
    QGridLayout* layout = new QGridLayout();
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setHorizontalSpacing(6);
    layout->setVerticalSpacing(0);

    // layout->setMinimunHeight() // Widget 才能设置最小高度

    item->setMinimumHeight(50); // 单条消息所占区域的最小高度
    item->setLayout(layout);

    // 2. 头像
    QPushButton* avatar = new QPushButton();
    avatar->setFixedSize(QSize(36, 36));
    avatar->setIconSize(QSize(36, 36));
    avatar->setIcon(msg.sender.avatar);
    avatar->setStyleSheet("QPushButton { border: none; background-color: transparent; }");
    if (isLeft)
    {
        layout->addWidget(avatar, 0, 0, 2, 2, Qt::AlignTop | Qt::AlignVCenter);
    }
    else
    {
        layout->addWidget(avatar, 0, 3, 2, 2, Qt::AlignTop | Qt::AlignVCenter);
    }

    // 3. 昵称和消息发送时间
    QLabel* name = new QLabel();
    name->setText(QString("%1 · %2").arg(msg.sender.nickname, msg.time));
    // name->setAlignment( Qt::AlignLeft);
    name->setStyleSheet("QLabel { color: rgb(178, 178, 178); font-size: 12px; }");
    if (isLeft)
    {
        name->setAlignment(Qt::AlignLeft | Qt::AlignTop);
        layout->addWidget(name, 0, 2, 1, 1);
    }
    else
    {
        name->setAlignment(Qt::AlignRight | Qt::AlignTop);
        layout->addWidget(name, 0, 0, 1, 1);
    }

    // 4. 消息体 -- 使用工厂方法创建
    QWidget* msg_body = nullptr;
    switch (msg.type)
    {
    case model::TEXT_MSG:
        msg_body = MakeTextMsgItem(isLeft, msg.content);
        break;
    // case model::IMAGE_MSG:
    //     msg_body = MakeImageMsgItem(isLeft, msg.fileId, msg.content);
    // case model::FILE_MSG:
    //     msg_body = MakeFileMsgItem(isLeft, msg);
    // case model::SPEECH_MSG:
    //     msg_body = MakeSpeechMsgItem(isLeft, msg);
    default:
        LOG() << "未知消息类型, msg_type = " << msg.type;
    }
    if (isLeft)
    {
        layout->addWidget(msg_body, 1, 2);
    }
    else
    {
        layout->addWidget(msg_body, 1, 0);
    }

    // 5. 连接槽函数

    // 6. 返回
    return item;
}

// 工厂函数
QWidget* MessageItem::MakeTextMsgItem(bool isLeft, const QString& text)
{
    MessageContentLabel* label = new MessageContentLabel(text, isLeft, model::TEXT_MSG, "", QByteArray());
    return label;
}
// QWidget* MessageItem::MakeImageMsgItem(bool isLeft, const QString& fileAddr, const QByteArray& content)
// {

// }
// QWidget* MessageItem::MakeFileMsgItem(bool isLeft, const Message& msg)
// {

// }
// QWidget* MessageItem::MakeSpeechMsgItem(bool isLeft, const Message& msg)
// {

// }


MessageContentLabel::MessageContentLabel(const QString& text, bool isLeft, const model::MessageType msgType,
                    const QString& fileAddr, const QByteArray& content)
    : is_left(isLeft), msg_type(msgType), file_addr(fileAddr), content(content)
{
    // 1. 设置基本属性
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    // 2. 设置 label
    QFont font;
    font.setPixelSize(14);
    font.setFamily("微软雅黑");

    label = new QLabel(this);
    label->setText(text);
    label->setFont(font);
    label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
    label->setWordWrap(true); // 自动换行
    // 边距：左右 7px
    label->setStyleSheet("QLabel { color: rgb(35, 35, 35); padding: 0 7px; line-height: 1.2; background-color: transparent; }");

    // 3. 文件消息特殊处理
}

void MessageContentLabel::paintEvent(QPaintEvent* event)
{
    // 1. 计算消息label的最大显示宽度
    QObject* obj = this->parent();
    if (obj->isWidgetType() == false)
        return;
    QWidget* parent = dynamic_cast<QWidget*>(obj);
    int width = parent->width() * 0.6;
    // qDebug() << "parent->width(): " << parent->width();

    // 2. 计算总文本宽度
    QFontMetrics metrics(label->font());
    int total_text_width = metrics.horizontalAdvance(label->text());

    // 3. 换算消息Label的行数、高度
    int rows = total_text_width / (width - 20) + 1;
    if (rows == 1)
        width = total_text_width + 20;
    int height = rows * (label->font().pixelSize()) * 1.36 + 20;


    // 4. 绘制消息label图案
    QPainter painter(this);
    QPainterPath path;
    painter.setRenderHint(QPainter::Antialiasing); // 设置反锯齿

    if (is_left)
    {
        painter.setPen(QPen(QColor(255, 255, 255)));
        painter.setBrush(QColor(255, 255, 255));
        // 绘制圆角矩形
        painter.drawRoundedRect(10, 8, width, height, 4, 4);
        // 绘制箭头
        path.moveTo(10, 18.5);
        path.lineTo(0, 27.5);
        path.lineTo(10, 36.5);
        path.closeSubpath(); // 闭合
        painter.drawPath(path);
        label->setGeometry(10, 8, width, height);
    }
    else
    {
        painter.setPen(QPen(QColor(149, 236, 105)));
        painter.setBrush(QColor(149, 236, 105));

        // 圆角矩形左边界
        int left_boundary = this->width() - width - 10; // 10 是用来容纳 箭头 的宽度
        // 圆角矩形右边界
        int right_boundary = this->width() - 10;
        // 绘制圆角矩形
        painter.drawRoundedRect(left_boundary, 8, width, height, 4, 4);
        // 绘制箭头
        path.moveTo(right_boundary, 18.5);
        path.lineTo(this->width(), 27.5);
        path.lineTo(right_boundary, 36.5);
        path.closeSubpath();
        painter.drawPath(path);

        this->label->setGeometry(left_boundary, 8, width, height);
    }
    // 5. 调整父元素宽度
    // parent->updateGeometry();
    parent->setFixedHeight(height+42);
}
